package com.incar.chuxing.baiduMap.MarkerOverlay;

import android.content.Context;

import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.utils.DistanceUtil;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.incar.chuxing.activity.MainActivity;
import com.incar.chuxing.api.ApiStore;
import com.incar.chuxing.api.RxApiStore;
import com.incar.chuxing.api.UrlContainer;
import com.incar.chuxing.application.MyApplication;
import com.incar.chuxing.bean.CarListBean;
import com.incar.chuxing.bean.CarListBean.AttachmentBean.ContentBean;
import com.incar.chuxing.bean.CarTrackBean;
import com.incar.chuxing.bean.CityBoundBean;
import com.incar.chuxing.bean.GoldCarListBean;
import com.incar.chuxing.bean.GoldCarTypeBean;
import com.incar.chuxing.bean.OpenedCityListBean;
import com.incar.chuxing.bean.PerPageCarsInfo;
import com.incar.chuxing.bean.RechargeDotBean;
import com.incar.chuxing.utils.Logger;
import com.incar.chuxing.utils.SPKey;
import com.incar.chuxing.utils.SPUtils;
import com.incar.chuxing.utils.StateType;
import com.incar.chuxing.utils.ThreadPool;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.BiFunction;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import static com.incar.chuxing.utils.StateType.LoadMarkerState.LOAD_FIRST_DONE;

/**
 * Created by michaelpi on 2018/4/4.
 */

public class OverlayUtils {

    private BaiduMap mBaiduMap;
    private Context mContext;
    public BoundOverlay boundOverlay;
    public MarkerOverlay markerOverlay;
    public String selectedMapIcon;
    public String version;
    public static final int LOAD_SUCCESS = 0;
    public static final int LOAD_ERROR = 1;
    public static final int LOAD_LOGOUT = 2;


    public LinkedHashMap<String, ContentBean> allCarList = new LinkedHashMap<>();//所有的车

    public List<ContentBean> nearCarList = new ArrayList<>();//分开的list 车信息
    public List<OpenedCityListBean.AttachmentBean.CityListBean> cityList = new ArrayList<>();//开通城市
    public List<CityBoundBean.AttachmentBean.FenceAreaBean> allBounds = new ArrayList<>();
    public static HashMap<Integer, HashMap<String, String>> goldBeanInfoMap = new HashMap<>();
    private CompositeDisposable compositeDisposable = new CompositeDisposable();
    public int goldBeanRadius;
    private boolean overRadius = false;
    private Observable<GoldCarTypeBean> goldTypeInfoObservable;
    private LatLng curPosition;

    public OverlayUtils(Context mContext, BaiduMap mBaiduMap) {
        this.mContext = mContext;
        this.mBaiduMap = mBaiduMap;
        boundOverlay = new BoundOverlay(mContext, mBaiduMap);
        markerOverlay = new MarkerOverlay(mContext, mBaiduMap);
    }


    public void getCarsByPage(LatLng curPosition, OnLoadCarResult onLoadCarResult) {
        compositeDisposable.clear();
        markerOverlay.carMarkerOptionsMap.clear();
        //先获取车图标
        RxApiStore.getInstance().getApiService(UrlContainer.Request.BASE_GATE_URL, 5).getAllIcon("multi-city/v1/cities/" + ((MyApplication) MyApplication.getInstance()).getAreaCode() + "/vehicles/icon")
                .retry(1)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<JsonObject>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(JsonObject carIconJson) {
                        //处理图片信息的书数据
                        if ("20001".equals(carIconJson.get("status").getAsString())) {//不需要更新图标信息

                        } else if ("200".equals(carIconJson.get("status").getAsString())) {//更新图标信息
                            // version = carIconJson.getAsJsonObject("attachment").get("version").getAsString();
                            Type typeMapPic = new TypeToken<Map<String, Map<String, String>>>() {
                            }.getType();
                            Type typeGradePic = new TypeToken<Map<String, String>>() {
                            }.getType();
                            try {
                                markerOverlay.picMap.put("mapPic", new Gson().fromJson(carIconJson.getAsJsonObject("attachment").getAsJsonObject("mapPic").toString(), typeMapPic));
                                markerOverlay.picMap.put("gradePic", new Gson().fromJson(carIconJson.getAsJsonObject("attachment").getAsJsonObject("gradePic").toString(), typeGradePic));
                                HashMap<String, String> map = new HashMap<String, String>();
                                map.put("trackIcon", carIconJson.getAsJsonObject("attachment").getAsJsonObject("carTrack").get("trackIcon").getAsString());
                                markerOverlay.picMap.put("carTrack", map);
                                //Logger.i("carTrackMap", carIconJson.getAsJsonObject("attachment").getAsJsonObject("carTrack").get("trackIcon").getAsString());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        //拿到图标后，分页加载车辆列表
                        getFirstCarListObservable(curPosition, onLoadCarResult);
                    }

                    @Override
                    public void onError(Throwable e) {
                        //加载车辆
                        getFirstCarListObservable(curPosition, onLoadCarResult);
                        Logger.d("图片接口有错误");
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    //生成每页的复合Observable
    private Observable<PerPageCarsInfo> getPerCarListObservable(int curCarPage, Observable<CarListBean> firstPageRelayObservable) {
        Logger.d("goldBean", "this step9 生成每页Observable" + curCarPage);

        Observable<CarListBean> perPageObservable;
        if (curCarPage == 1) {
            perPageObservable = firstPageRelayObservable;
        } else {
            perPageObservable = RxApiStore.getInstance().getApiService(UrlContainer.Request.BASE_GATE_URL).getCars(((MyApplication) MyApplication.getInstance()).getRequestFieldMap(), curCarPage + "")
                    .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
        }


        //合并请求第一页和金豆类型信息后，获取金豆车列表
        return Observable
                .zip(perPageObservable, goldTypeInfoObservable, new BiFunction<CarListBean, GoldCarTypeBean, CarListBean>() {
                    @Override
                    public CarListBean apply(CarListBean carListBean, GoldCarTypeBean goldCarTypeBean) throws Exception {
                        if (goldCarTypeBean != null && goldCarTypeBean.getMsg_code() == 200 && goldCarTypeBean.getAttachment().getList() != null) {
                            goldBeanRadius = goldCarTypeBean.getAttachment().getChoice_car_area() * 1000;//金豆车半径
                            //生成金豆车类型信息
                            createGoldInfoMap(goldCarTypeBean.getAttachment().getList());
                        }
                        return carListBean;
                    }
                })
                .subscribeOn(Schedulers.computation())
                .flatMap(new Function<CarListBean, ObservableSource<PerPageCarsInfo>>() {
                    @Override
                    public ObservableSource<PerPageCarsInfo> apply(CarListBean carListBean) throws Exception {
                        PerPageCarsInfo perPageCarsInfo = new PerPageCarsInfo();//包装车列表信息、页码和接口状态码
                        perPageCarsInfo.setPageNo(curCarPage);
                        perPageCarsInfo.setStatus(carListBean.getStatus());

                        if (carListBean.getStatus() != 200 || carListBean.getAttachment().getContent() == null) {//此页没有车
                            Logger.d("goldBean", "this step 没有车辆,不再计算金豆车");
                            return Observable.create(emitter -> {
                                emitter.onNext(perPageCarsInfo);
                                emitter.onComplete();
                            });
                        }


                        //把车列表List转成Map
                        LinkedHashMap<String, ContentBean> perPageCarMap = new LinkedHashMap<>();
                        for (ContentBean contentBean : carListBean.getAttachment().getContent()) {
                            perPageCarMap.put(contentBean.getId(), contentBean);
                        }
                        perPageCarsInfo.setPerPageCarMap(perPageCarMap);


                        if (goldBeanInfoMap.size() == 0 || overRadius) {//如果没有获取到金豆车信息，不再获取金豆车列表；或者上一页已经标识没有范围内的金豆车了
                            Logger.d("goldBean", "this step 超出金豆范围,不再计算金豆车");
                            return Observable.create(emitter -> {
                                emitter.onNext(perPageCarsInfo);
                                emitter.onComplete();
                            });
                        }


                        //如果拿到金豆车信息，开始获取金豆车列表，并刷新车辆列表数据
                        ArrayList<Integer> carIds = new ArrayList<>();
                        for (ContentBean contentBean : perPageCarsInfo.getPerPageCarMap().values()) {
                            if (DistanceUtil.getDistance(curPosition, new LatLng(contentBean.getLatitude(), contentBean.getLongitude())) < goldBeanRadius) {
                                carIds.add(Integer.parseInt(contentBean.getId()));
                            }
                        }

                        if (carIds.size() < perPageCarsInfo.getPerPageCarMap().size()) {//说明此页有大于阈值距离的车，下一页不再请求金豆车数据
                            overRadius = true;
                        }
                        Logger.d("goldBean", "this step3 标识金豆是否还有超出范围  " + (overRadius ? "超出" : "未超出") + "   carIds=" + carIds.size());

                        if (carIds.size() > 0) {
                            JSONObject bodyJson = new JSONObject();
                            try {
                                JSONArray jsonArray = new JSONArray(new Gson().toJson(carIds));
                                bodyJson.put("car_ids", jsonArray);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                            RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), bodyJson.toString());

                            return RxApiStore.getInstance().getApiService(UrlContainer.Request.BASE_GATE_URL, 10).getGoldCarList(body)
                                    .map(new Function<GoldCarListBean, PerPageCarsInfo>() {
                                        @Override
                                        public PerPageCarsInfo apply(GoldCarListBean goldCarListBean) throws Exception {
                                            List<GoldCarListBean.AttachmentBean> goldList = goldCarListBean.getAttachment();
                                            for (GoldCarListBean.AttachmentBean goldBean : goldList) {
                                                //根据金豆车的carId从车列表中匹配查找
                                                ContentBean contentBean = perPageCarMap.get(goldBean.getCar_id());
                                                contentBean.setGoldCarType(goldBean.getGold_car_type());
                                                contentBean.setGoldCarStatus(goldBean.getCar_status());
                                                contentBean.setGoldCarMinutes(goldBean.getShort_minutes());
                                                if (goldBean.getCar_status() == 1) {//查找金豆车图片
                                                    contentBean.setGoldPic(goldBeanInfoMap.get(goldBean.getGold_car_type()).get("half_gold_icon"));
                                                } else if (goldBean.getCar_status() == 2) {
                                                    contentBean.setGoldPic(goldBeanInfoMap.get(goldBean.getGold_car_type()).get("gold_icon"));
                                                }
                                            }
                                            return perPageCarsInfo;
                                        }
                                    })
                                    .onErrorResumeNext(throwable -> {
                                        Logger.d("goldBean", "this step5 获取金豆车列表错误" + throwable.getMessage());
                                        throwable.printStackTrace();
                                        return Observable.create(emitter -> {
                                            emitter.onNext(perPageCarsInfo);//获取列表错误
                                            emitter.onComplete();
                                        });
                                    })
                                    .subscribeOn(Schedulers.io())
                                    .observeOn(AndroidSchedulers.mainThread());
                        } else {
                            return Observable.create(emitter -> {
                                emitter.onNext(perPageCarsInfo);//没有范围内的车
                                emitter.onComplete();
                            });

                        }

                    }
                });
    }

    private void createGoldInfoMap(List<GoldCarTypeBean.AttachmentBean.ListBean> list) {
        for (GoldCarTypeBean.AttachmentBean.ListBean listBean : list) {
            HashMap<String, String> carTypeMap = new HashMap<>();
            carTypeMap.put("half_gold_icon", listBean.getHalf_gold_icon());
            carTypeMap.put("gold_icon", listBean.getGold_icon());
            carTypeMap.put("icon_text", listBean.getIcon_text());
            carTypeMap.put("show_full_text", listBean.getShow_full_text());
            carTypeMap.put("show_half_text", listBean.getShow_half_text());
            carTypeMap.put("link_text", listBean.getLink_text());
            carTypeMap.put("link_href", listBean.getLink_href());
            carTypeMap.put("real_time_icon", listBean.getReal_time_icon());
            goldBeanInfoMap.put(listBean.getGold_car_type(), carTypeMap);
        }
    }


    private void getFirstCarListObservable(LatLng curPosition, OnLoadCarResult onLoadCarResult) {
        this.curPosition = curPosition;
        overRadius = false;//重置

        //金豆车类型信息
        goldTypeInfoObservable = RxApiStore.getInstance().getApiService(UrlContainer.Request.BASE_GATE_URL, 5).getGoldBeanTypeInfo(((MyApplication) MyApplication.getInstance()).getRequestFieldMap(), ((MyApplication) MyApplication.getInstance()).getAreaCode())
                //.retry(1)
                .onErrorResumeNext(throwable -> {
                    return Observable.create(emitter -> {
                        Logger.d("goldBean", "cache金豆");
                        emitter.onNext(new GoldCarTypeBean());//没有围栏发送false
                        emitter.onComplete();
                    });
                })
                .cache()
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());

        //从第一页拿到总页数，开始生成其他页的Observable
        RxApiStore.getInstance().getApiService(UrlContainer.Request.BASE_GATE_URL).getCars(((MyApplication) MyApplication.getInstance()).getRequestFieldMap(), 1 + "")
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                .flatMap(carListBean -> {

                    if (carListBean.getStatus() != 200 || carListBean.getAttachment() == null) {
                        return Observable.error(new Throwable("第一页数据错误"));
                    }

                    //把第一页的数据和其他页的数据，统一出口输出
                    Observable<CarListBean> firstPageRelayObservable = Observable.create(emitter -> {
                        emitter.onNext(carListBean);
                        emitter.onComplete();
                    });
                    Logger.d("goldBean", "this step8 总页数" + carListBean.getAttachment().getTotalPage());

                    ArrayList<Observable<PerPageCarsInfo>> list = new ArrayList<>();
                    list.add(getPerCarListObservable(1, firstPageRelayObservable));
                    for (int j = 2; j <= carListBean.getAttachment().getTotalPage(); j++) {
                        list.add(getPerCarListObservable(j, firstPageRelayObservable));
                        Logger.d("goldBean", "this step11 添加了一个分页" + j);
                    }
                    Logger.d("goldBean", "this step10 生成每页完毕");
                    return Observable.concatDelayError(list);//开始有序分页请求
                })
                .subscribe(new Observer<PerPageCarsInfo>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        compositeDisposable.add(d);
                        Logger.d("goldBean", "this step11 已订阅");
                    }

                    @Override
                    public void onNext(PerPageCarsInfo perPageCarsInfo) {
                        Logger.d("goldBean", "第几页" + perPageCarsInfo.getPageNo());
                        if (perPageCarsInfo.getStatus() == 200) {
                            //第一页加载完毕
                            if (perPageCarsInfo.getPageNo() == 1) {
                                if (StateType.isEqualsCurStates(StateType.State.DEFAULT)) {
                                    markerOverlay.hideInfoWindow();
                                    clearMap();
                                    StateType.setCurState(StateType.State.DEFAULT);
                                    markerOverlay.carMarkerOptionsMap.clear();
                                    allCarList.clear();
                                    Logger.d("jsonPhraseResult", "清除完毕完毕");
                                }
                            }

                            if (perPageCarsInfo.getPerPageCarMap() != null) {
                                Logger.d("goldBean", "添加一页数据");
                                allCarList.putAll(perPageCarsInfo.getPerPageCarMap());
                                markerOverlay.addCarsMarker(perPageCarsInfo.getPerPageCarMap());
                            }

                            if (perPageCarsInfo.getPageNo() == 1) {
                                Logger.d("goldBean", "通知第一页完毕");
                                StateType.loadState = LOAD_FIRST_DONE;
                                onLoadCarResult.onFirstPageLoadDone(LOAD_SUCCESS, "");
                            }

                        } else if (perPageCarsInfo.getStatus() == 20) {//退出登录
                            if (perPageCarsInfo.getPageNo() == 1) {
                                onLoadCarResult.onFirstPageLoadDone(LOAD_LOGOUT, "");
                            } else {
                                onLoadCarResult.onCarsLoadDone(LOAD_LOGOUT, "");
                            }

                        } else {//服务器错误
                            StateType.loadState = StateType.LoadMarkerState.LOAD_DONE;
                            if (perPageCarsInfo.getPageNo() == 1) {
                                onLoadCarResult.onFirstPageLoadDone(LOAD_ERROR, "第一页车辆分页接口服务错误");
                            } else {
                                onLoadCarResult.onCarsLoadDone(LOAD_ERROR, "车辆分页接口服务错误");
                            }
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        StateType.loadState = StateType.LoadMarkerState.LOAD_DONE;
                        onLoadCarResult.onFirstPageLoadDone(LOAD_ERROR, "服务器异常，请稍后重试");
                        Logger.d("goldBean", "车接口有错误");

                        e.printStackTrace();
                    }

                    @Override
                    public void onComplete() {
                        //所有的车加载后，设置加载状态为加载完成
                        Logger.d("goldBean", "所有分页加载完毕");
                        StateType.loadState = StateType.LoadMarkerState.LOAD_DONE;
                    }
                });
    }

    /**
     * 渲染所有的车辆到地图（所有页的车辆数据）
     */
    public void addAllPagesCarsMarker() {
        markerOverlay.addAllCars();
    }

    /**
     * 获取附近20辆，并渲染到地图
     */

    public void getNearTwenty(LatLng curPosition, OnLoadNearResult onLoadNearResult) {
        //如果距离上次计算20辆的时间小于2分钟并且上次计算的结果不小于20辆，则直接使用上次的计算结果。如果上次重新获取了所有的车则REFRESH_NEAR_TIME被置零，此时也重新计算20辆。
        if ((new Date().getTime() - SPUtils.getInstance(mContext).getLongValue(SPKey.REFRESH_NEAR_TIME)) < 120000 && nearCarList.size() >= 20) {
            onLoadNearResult.onLoadNearDone(LOAD_SUCCESS, nearCarList);
        } else {
            ArrayList<ContentBean> allCarsList = new ArrayList<>(allCarList.values());//所有的车和网点，用于筛选附近的20辆
            ArrayList<ContentBean> partCarsList = new ArrayList<>();
            nearCarList.clear();
            if (allCarsList.size() > 1000) {
                partCarsList.addAll(allCarsList.subList(0, 1000));
            } else {
                partCarsList.addAll(allCarsList);
            }
            Logger.i("nearList", allCarList.size() + "allCarListsize");
            ThreadPool.execute(() -> {
                Collections.sort(partCarsList, (o1, o2) -> {
                    if (getDistance(curPosition.latitude, curPosition.longitude, o1.getLatitude(), o1.getLongitude())
                            - getDistance(curPosition.latitude, curPosition.longitude, o2.getLatitude(), o2.getLongitude()) > 0) {
                        return 1;
                    } else if (getDistance(curPosition.latitude, curPosition.longitude, o1.getLatitude(), o1.getLongitude())
                            - getDistance(curPosition.latitude, curPosition.longitude, o2.getLatitude(), o2.getLongitude()) < 0) {
                        return -1;
                    } else {
                        return 0;
                    }
                });

                Logger.i("nearList", partCarsList.size() + "allCarsAndParksListSize");
                for (int i = 0; i <= 20 && i < partCarsList.size(); i++) {
                    nearCarList.add(partCarsList.get(i));
                    if (nearCarList.size() >= 20) break;
                }
                ((MainActivity) mContext).runOnUiThread(() -> {
                    if (nearCarList != null && nearCarList.size() != 0) {
                        onLoadNearResult.onLoadNearDone(LOAD_SUCCESS, nearCarList);
                        Logger.i("nearList", nearCarList.size() + "nearCarListsize");
                    } else {
                        onLoadNearResult.onLoadNearDone(LOAD_ERROR, null);
                    }
                });
                SPUtils.getInstance(mContext).putLongValue(SPKey.REFRESH_NEAR_TIME, new Date().getTime());
            });
        }
    }

    private Disposable carTrackDisposable;

    public void getReturnCarTrack(String carId) {
        //上个用户的行车轨迹
        if (carTrackDisposable != null)
            carTrackDisposable.dispose();
        RxApiStore.getInstance().getApiService(UrlContainer.Request.BASE_GATE_URL, 5).getCarTrack(((MyApplication) MyApplication.getInstance()).getRequestFieldMap(), carId)
                .retry(1)
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<CarTrackBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        carTrackDisposable = d;
                    }

                    @Override
                    public void onNext(CarTrackBean carTrackBean) {

                        if (carTrackBean.getStatus() == 200) {
                            if (carTrackBean.getAttachment() != null && carTrackBean.getAttachment().size() > 1) {
                                addCarTrack(carTrackBean.getAttachment());
                            }
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        Logger.d("获取轨迹错误");
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    private double getDistance(double lat1, double lng1, double lat2, double lng2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        return Math.pow(Math.sin(a / 2), 2)
                + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2)
                , 2);
    }

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    public void addReChargeDotMarker
            (List<RechargeDotBean.AttachmentBean.ElectricStationBean> electricStationBeans) {
        markerOverlay.addReChargeDotMarker(electricStationBeans);
    }

    public void addGasolineDotMarker(List<PoiInfo> poiInfos) {
        markerOverlay.addGasolineDotMarker(poiInfos);
    }

    public void addFindCar(LatLng position, String selectedMapIcon) {
        markerOverlay.addFindCar(position, selectedMapIcon);
    }

    public void addSelectedCar(ContentBean carBean, boolean recordLastSelected) {
        hideInfoWindow();
        markerOverlay.addSelectedCar(carBean, allCarList, recordLastSelected);
    }

    public void addLineStartIcon(double latitude, double longitude) {
        markerOverlay.addLineStartIcon(latitude, longitude);
    }


    public void getCityList() {
        ApiStore.getInstance().getApiService(UrlContainer.Request.BASE_GATE_URL).getCityList(((MyApplication) mContext.getApplicationContext()).getRequestFieldMap())
                .enqueue(new Callback<OpenedCityListBean>() {
                    @Override
                    public void onResponse(Call<OpenedCityListBean> call, Response<OpenedCityListBean> response) {
                        if (response.isSuccessful() && response.body() != null && null != response.body().getAttachment()) {
                            cityList = response.body().getAttachment().getCityList();
                            markerOverlay.createCitiesMarker(cityList);
                        }
                    }

                    @Override
                    public void onFailure(Call<OpenedCityListBean> call, Throwable t) {
                        /* ToastUtils.makeText(mContext, mContext.getResources().getString(R.string.badNetwork), ToastUtils.LENGTH_SHORT).show();*/
                        Logger.d("netError", "102 " + t.toString());
                    }
                });
    }

    public void addCitiesMarkerToMap() {
        if (cityList.size() != 0) {
            markerOverlay.addCitiesToMap(cityList);
        } else {
            getCityList();
        }

    }


    public void showCarLocationInfoWindow(ContentBean contentBean) {
        /*
         *icon_text : 展示文字
         *show_full_text : 我是一辆时长优惠金豆车
         *show_half_text : 还差[min]分钟升级时长优惠金豆车
         *link_text :  金豆车是什么？
         *link_href : http://
         *real_time_icon : 行驶中实时活动图片id
         */

        //carMergeInfo.setIcon_text(goldBeanInfoMap.get(carMergeInfo.getGold_car_type()).get("icon_text"));
        if (contentBean.getGoldCarStatus() != 0) {
            contentBean.setLink_text(goldBeanInfoMap.get(contentBean.getGoldCarType()).get("link_text"));
            contentBean.setLink_href(goldBeanInfoMap.get(contentBean.getGoldCarType()).get("link_href"));
            if (contentBean.getGoldCarStatus() == 1) {//半金豆车
                contentBean.setShow_text(goldBeanInfoMap.get(contentBean.getGoldCarType()).get("show_half_text").replace("[min]", contentBean.getGoldCarMinutes() + ""));
            } else if (contentBean.getGoldCarStatus() == 2) {//金豆车
                contentBean.setShow_text(goldBeanInfoMap.get(contentBean.getGoldCarType()).get("show_full_text"));
            }
        }
        markerOverlay.showCarLocationInfoWindow(contentBean);
    }

    public void showFindCarInfoWindow(ContentBean contentBean, int type) {
        if (contentBean.getGoldCarStatus() != 0) {
            contentBean.setLink_text(goldBeanInfoMap.get(contentBean.getGoldCarType()).get("link_text"));
            contentBean.setLink_href(goldBeanInfoMap.get(contentBean.getGoldCarType()).get("link_href"));
            if (contentBean.getGoldCarStatus() == 1) {//半金豆车
                contentBean.setShow_text(goldBeanInfoMap.get(contentBean.getGoldCarType()).get("show_half_text").replace("[min]", contentBean.getGoldCarMinutes() + ""));
            } else if (contentBean.getGoldCarStatus() == 2) {//金豆车
                contentBean.setShow_text(goldBeanInfoMap.get(contentBean.getGoldCarType()).get("show_full_text"));
            }
        }
        markerOverlay.showFindCarInfoWindow(contentBean, type);
    }

    public void showFindRechargeDotInfoWindow(String content, LatLng
            carPosition, MarkerOverlay.NaviButtonClickListener clickListener) {
        markerOverlay.showFindRechargeDotInfoWindow(content, carPosition, clickListener);
    }

    public void showDrivingCarInfoWindow(String longtime, double distance, String endTime, LatLng markerPosition) {
        markerOverlay.showDrivingCarInfoWindow(longtime, distance, endTime, markerPosition);
    }


    public void removeRechargeDotMarker() {
        markerOverlay.removeRechargeDotMarker();
    }

    public void removeGasolineDotMarker() {
        markerOverlay.removeGasolineDotMarker();
    }

    public void removeNearTwentyMarker() {
        markerOverlay.removeNearTwentyMarker();
    }

    public void clearSelectedMarker() {
        markerOverlay.clearSelectedMarker();
    }

    public void hideInfoWindow() {
        markerOverlay.hideInfoWindow();
    }


    public void addBounds() {
        if (StateType.isEqualsCurStates(StateType.State.SHOW_CITY)) {
            return;
        }
        boundOverlay.addBounds(allBounds, mBaiduMap.getMapStatus().zoom);
        markerOverlay.addBoundMarker(allBounds);
    }

    public void addBoundsDriving() {
        boundOverlay.addBounds(allBounds, mBaiduMap.getMapStatus().zoom);
        markerOverlay.addBoundMarker(allBounds);
    }


    public void addCarTrack(List<CarTrackBean.AttachmentBean> lineBeans) {
        boundOverlay.addCarTrack(lineBeans);
        markerOverlay.addLineStartIcon(lineBeans.get(0).getLatitude(), lineBeans.get(0).getLongitude());

    }

    //添加预订单maker
    public void addPreOrderMarker(LatLng latLng) {
        markerOverlay.addPreOrderMarker(latLng);
    }

    //显示预订单infowWindow
    public void showDeliverCarOrderLocInfoWindow(LatLng latLng) {
        markerOverlay.showDeliverCarOrderLocInfoWindow(latLng);
    }

    //显示预订单infowWindowAndPhone
    public void showDeliverCarOrderLocInfoWindowAndPhone(LatLng latLng, MarkerOverlay.DeliverPhoneClickListener clickListener) {
        markerOverlay.showDeliverCarOrderLocInfoWindowAndPhone(latLng, clickListener);
    }

    /**
     * 清除地图上网点和车辆的Marker
     */
    public void clearMap() {
        mBaiduMap.clear();
        markerOverlay.clearData();
        boundOverlay.clearData();
        //addBounds();
    }

    public void updateOneMarkerInfo(ContentBean carBean) {
        markerOverlay.updateOneMarkerInfo(carBean);
    }


    /**
     * 分页加载的结果
     */
    public interface OnLoadCarResult {
        void onFirstPageLoadDone(int errorCode, String error);

        void onCarsLoadDone(int errorCode, String error);

    }

    /**
     * 计算附近二十辆的结果
     */
    public interface OnLoadNearResult {
        void onLoadNearDone(int errorCode, List<ContentBean> nearCarList);

    }


    public int carIdToCarListIndex(String carMarkerId) {
        for (int i = 0; i < allCarList.size(); i++) {
            if (allCarList.get(i).getId().equals(carMarkerId)) {
                return i;
            }
        }
        return 0;
    }


    public boolean isShowNearCar(LatLng curPosition) {
        if (allCarList.size() != 0) {
            List<Double> distance = new ArrayList<>();
            for (CarListBean.AttachmentBean.ContentBean carModelsBean : allCarList.values()) {
                LatLng nearest = new LatLng(carModelsBean.getLatitude(), carModelsBean.getLongitude());
                Double Distance = DistanceUtil.getDistance(curPosition, nearest);
                distance.add(Distance);
            }
            double nearestDistance = Collections.min(distance);
            return nearestDistance < 100 && !SPUtils.getInstance(mContext).getBooleanValue(SPKey.LONG_CLICK_TIP);
        }
        return false;
    }


    public ContentBean getNearOneCar(LatLng curPosition) {

        ArrayList<ContentBean> allCarsList = new ArrayList<>(allCarList.values());//所有的车和网点，用于筛选附近的20辆
        ArrayList<ContentBean> partCarsList = new ArrayList<>();
        nearCarList.clear();
        if (allCarsList.size() > 1000) {
            partCarsList.addAll(allCarsList.subList(0, 1000));
        } else {
            partCarsList.addAll(allCarsList);
        }

        Collections.sort(partCarsList, (o1, o2) -> {
            if (getDistance(curPosition.latitude, curPosition.longitude, o1.getLatitude(), o1.getLongitude())
                    - getDistance(curPosition.latitude, curPosition.longitude, o2.getLatitude(), o2.getLongitude()) > 0) {
                return 1;
            } else if (getDistance(curPosition.latitude, curPosition.longitude, o1.getLatitude(), o1.getLongitude())
                    - getDistance(curPosition.latitude, curPosition.longitude, o2.getLatitude(), o2.getLongitude()) < 0) {
                return -1;
            } else {
                return 0;
            }
        });
        if (!partCarsList.isEmpty()) {
            return partCarsList.get(0);
        }

        return null;
    }

    public BitmapDescriptor createLocationIcon() {
        return markerOverlay.createLocationIcon();
    }

    public void initSendCarEntry() {
        markerOverlay.initSendCarEntry();
    }

    public void addSendCarMarker() {
        markerOverlay.addSendCarMarker();
    }


}
